package com.example.shuiyin.utils;

import com.example.shuiyin.exception.AppException;
import com.example.shuiyin.exception.ErrorCode;
import com.example.shuiyin.enums.TextStyle;
import com.example.shuiyin.enums.WatermarkPosition;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacpp.indexer.UByteIndexer;
import org.bytedeco.javacpp.IntPointer;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.*;
import org.springframework.stereotype.Component;

import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_photo.*;

@Component
@Slf4j
public class OpenCVUtils {

    /**
     * 去除图片水印
     * @param inputPath 输入图片路径
     * @param outputPath 输出图片路径
     * @return 处理后的图片路径
     */
    public String removeWatermark(String inputPath, String outputPath) {
        log.info("开始处理图片水印: {} -> {}", inputPath, outputPath);
        
        try {
            // 读取图片
            Mat image = imread(inputPath);
            if (image.empty()) {
                throw new AppException("无法读取图片文件: " + inputPath, ErrorCode.INTERNAL_SERVER_ERROR);
            }
            
            // 获取图片尺寸
            int width = image.cols();
            int height = image.rows();
            
            // 创建水印掩码 - 假设水印在右下角
            int watermarkX = (int)(width * 0.7);  // 右边70%位置
            int watermarkY = (int)(height * 0.8); // 底部20%位置
            int watermarkWidth = (int)(width * 0.3); // 宽度30%
            int watermarkHeight = (int)(height * 0.2); // 高度20%
            
            // 创建掩码
            Mat mask = new Mat(height, width, CV_8UC1, Scalar.BLACK);
            rectangle(mask, 
                      new Point(watermarkX, watermarkY), 
                      new Point(watermarkX + watermarkWidth, watermarkY + watermarkHeight), 
                      Scalar.WHITE, 
                      FILLED, 
                      LINE_8, 
                      0);
            
            // 创建修复的目标区域
            Mat inpaintMask = mask.clone();
            
            // 应用修复算法 (INPAINT_TELEA or INPAINT_NS)
            Mat result = new Mat();
            inpaint(image, inpaintMask, result, 3, INPAINT_TELEA);
            
            // 保存结果
            imwrite(outputPath, result);
            
            log.info("图片水印处理完成");
            return outputPath;
            
        } catch (Exception e) {
            log.error("处理图片水印失败", e);
            throw new AppException("处理图片水印失败: " + e.getMessage(), ErrorCode.INTERNAL_SERVER_ERROR);
        }
    }

    public static Mat readImage(String inputPath) {
        Mat image = imread(inputPath);
        if (image.empty()) {
            throw new AppException("无法读取图片文件: " + inputPath, ErrorCode.INTERNAL_SERVER_ERROR);
        }
        return image;
    }

    public static void addWatermarkToImage(String inputPath, String outputPath, String watermarkText, 
                                         WatermarkPosition position, TextStyle textStyle) {
        try {
            // 读取原始图片
            Mat image = imread(inputPath);
            if (image.empty()) {
                throw new AppException("无法读取图片文件: " + inputPath, ErrorCode.INTERNAL_SERVER_ERROR);
            }
            
            // 获取图片尺寸
            int width = image.cols();
            int height = image.rows();
            
            // 设置文本样式
            int fontFace = FONT_HERSHEY_SIMPLEX;
            double fontScale = 1.0;
            int thickness = 2;
            
            if (textStyle == TextStyle.BOLD) {
                thickness = 3;
            } else if (textStyle == TextStyle.ITALIC) {
                fontFace = FONT_ITALIC;
            } else if (textStyle == TextStyle.BOLD_ITALIC) {
                fontFace = FONT_ITALIC;
                thickness = 3;
            }
            
            // 计算文本大小
            IntPointer baseLine = new IntPointer(1);
            Size textSize = getTextSize(watermarkText, fontFace, fontScale, thickness, baseLine);
            int textWidth = (int) textSize.width();
            int textHeight = (int) textSize.height();
            
            // 计算文本位置
            Point textPosition = new Point();
            
            switch (position) {
                case TOP_LEFT:
                    textPosition.x(20);
                    textPosition.y(textHeight + 20);
                    break;
                case TOP_CENTER:
                    textPosition.x((width - textWidth) / 2);
                    textPosition.y(textHeight + 20);
                    break;
                case TOP_RIGHT:
                    textPosition.x(width - textWidth - 20);
                    textPosition.y(textHeight + 20);
                    break;
                case MIDDLE_LEFT:
                    textPosition.x(20);
                    textPosition.y((height + textHeight) / 2);
                    break;
                case MIDDLE_CENTER:
                    textPosition.x((width - textWidth) / 2);
                    textPosition.y((height + textHeight) / 2);
                    break;
                case MIDDLE_RIGHT:
                    textPosition.x(width - textWidth - 20);
                    textPosition.y((height + textHeight) / 2);
                    break;
                case BOTTOM_LEFT:
                    textPosition.x(20);
                    textPosition.y(height - 20);
                    break;
                case BOTTOM_CENTER:
                    textPosition.x((width - textWidth) / 2);
                    textPosition.y(height - 20);
                    break;
                case BOTTOM_RIGHT:
                default:
                    textPosition.x(width - textWidth - 20);
                    textPosition.y(height - 20);
                    break;
            }
            
            // 添加文本水印
            putText(image, watermarkText, textPosition, fontFace, fontScale, Scalar.WHITE, thickness, LINE_AA, false);
            
            // 保存结果
            imwrite(outputPath, image);
            
        } catch (Exception e) {
            log.error("处理图片水印失败: {}", e.getMessage(), e);
            throw new AppException("处理图片水印失败: " + e.getMessage(), ErrorCode.INTERNAL_SERVER_ERROR);
        }
    }
} 